package com.ysy.logistics.service.device.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ysy.common.myenum.StatusEnum;
import com.ysy.logistics.entities.device.Device;
import com.ysy.logistics.entities.device.DeviceLife;
import com.ysy.logistics.entities.oam.OperationLog;
import com.ysy.logistics.entities.stock.StoreHouse;
import com.ysy.logistics.mapper.device.DeviceLifeMapper;
import com.ysy.logistics.mapper.device.DeviceMapper;
import com.ysy.logistics.mapper.stock.StoreHouseMapper;
import com.ysy.logistics.myenum.DeviceType;
import com.ysy.logistics.service.device.DeviceLifeService;
import com.ysy.logistics.service.system.SysNoticeService;
import com.ysy.logistics.util.PageInfo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author 姚斯羽
 * @date 2025/4/20 19:55
 * @description:
 */
@Service
@Slf4j
public class DeviceLifeServiceImpl extends ServiceImpl<DeviceLifeMapper, DeviceLife> implements DeviceLifeService {

    @Resource
    private DeviceLifeMapper deviceLifeMapper;
    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private StoreHouseMapper storeHouseMapper;
    @Resource
    private SysNoticeService sysNoticeService;

    /**
     * 每十分钟保存一次设备生命周期 ，模拟生命周期
     */
    @Scheduled(cron = "0 0/10 * * * ?")
    public void saveDeviceLife() {
        log.debug("模拟设备生命周期");
        // 获取所有设备
        LambdaQueryWrapper<Device> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Device::getStatus, StatusEnum.ENABLE.getCode())
                .eq(Device::getDeleted, 0);
        List<Device> devices = deviceMapper.selectList(lqw);
        //设备生命周期列表
        List<DeviceLife> deviceLifes = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(devices)) {
            //设备上限值
            devices.stream().forEach(device -> {
                //设备范围值
                Integer upperThreshold = device.getUpperThreshold();
                Integer lowerThreshold = device.getLowerThreshold();
                //是否正常
                Boolean flag = !getOneThousand();
                //构建生命周期对象
                DeviceLife deviceLife = new DeviceLife();
                deviceLife.setDeviceId(device.getId())
                        .setRecordTime(new Date());
                if (flag) {
                    //正常 生成 范围值的数据
                    deviceLife = getRandomNum(upperThreshold, lowerThreshold,deviceLife);
                } else {
                    //不正常，生成范围外的值
                    deviceLife = getRandomNumOut(upperThreshold, lowerThreshold,deviceLife);
                }
                //如果设备异常发送消息
                if (deviceLife.getStatus()!= 0) {
                    //获取仓库信息
                    //查询出库房信息
                    StoreHouse storeHouse = storeHouseMapper.selectById(device.getWarehouseId());
                    String storeName = Optional.ofNullable(storeHouse).map(StoreHouse::getName).orElse("");
                    String title ="仓库[" + storeName + "]设备报警";
                    String content = String.format( "%s 所在仓库,",storeName);
                    if (device.getDeviceType().equals(DeviceType.WD.getCode())){
                        if (deviceLife.getStatus()<0){
                            content += "温度过低，请调高仓库温度";
                        }else {
                            content += "温度过高，请调低仓库温度";
                        }
                    }else if(device.getDeviceType().equals(DeviceType.SD.getCode())){
                        if (deviceLife.getStatus()<0){
                            content += "湿度过低，请调高仓库湿度";
                        }else {
                            content += "湿度过高，请调低仓库湿度";
                        }
                    }
                    //发送消息
                    sysNoticeService.saveNoticeDevice(title,content);
                }
                deviceLifes.add(deviceLife);
            });
        }
        //保存生命周期到数据库
        deviceLifeMapper.insert(deviceLifes);
    }

    /**
     * 千分之一概率返回true
     */
    private boolean getOneThousand() {
        return Math.random() < 0.001;
    }

    /**
     * 50%概率返回true
     */
    private boolean getHundred() {
        return Math.random() < 0.5;
    }

    /**
     * 生成范围内的数字
     */
    private DeviceLife getRandomNum(Integer lowerThreshold, Integer upperThreshold, DeviceLife deviceLife) {
        if (deviceLife == null){
            deviceLife = new DeviceLife();
            deviceLife.setStatus(0);
        }
        Integer low = lowerThreshold;
        Integer high = upperThreshold;
        if (low == null) {
            low = 0;
        }
        if (high == null) {
            high = 0;
        }

        if (low > high) {
            Integer temp = low;
            low = high;
            high = temp;
        }
        //范围内的数字
        Integer num = high - low;
        Integer v = (int) (Math.random() * (num));
        if (upperThreshold != null) {
            return  deviceLife.setDeviceNum(high - v);
        }
        return deviceLife.setDeviceNum(low + v );
    }

    /**
     * 生成范围外的数字
     */
    private DeviceLife getRandomNumOut(Integer lowerThreshold, Integer upperThreshold,DeviceLife deviceLife) {
        if (deviceLife == null){
            deviceLife = new DeviceLife();
        }
        Integer low = lowerThreshold;
        Integer high = upperThreshold;
        if (low == null) {
            low = 0;
        }
        if (high == null) {
            high = 0;
        }

        if (low > high) {
            Integer temp = low;
            low = high;
            high = temp;
        }
        //范围内的数字
        Integer num = high - low;
        Integer v =(int) (Math.random() * (num));
        //上限还是下限
        boolean flag = getHundred();
        if ((flag && upperThreshold != null) || lowerThreshold == null){
            deviceLife.setStatus(1);
            return deviceLife.setDeviceNum(high + v);
        }else if (lowerThreshold !=null){
            deviceLife.setStatus(-1);
            return deviceLife.setDeviceNum(low - v);
        }
        deviceLife.setStatus(0);
        return deviceLife.setDeviceNum(low + v);

    }

    @Override
    public Page<DeviceLife> getListByPage(PageInfo<DeviceLife> pageInfo) {
        //获取参数
        log.debug("分页查询设备记录："+pageInfo);
        LocalDate beginTime = pageInfo.getBeginTime();
        LocalDate endTime = pageInfo.getEndTime();
        if (beginTime != null && endTime != null){
            LocalDate temp = beginTime;
            endTime = beginTime.isAfter(endTime)?beginTime:endTime;
            beginTime = temp;
        }
        LambdaQueryWrapper<DeviceLife> lqw = new LambdaQueryWrapper();
        if (beginTime!=null){
            lqw.ge(DeviceLife::getRecordTime,beginTime.atStartOfDay());
        }
        if (endTime!=null){
            //+1天
            endTime.plusDays(1);
            lqw.le(DeviceLife::getRecordTime,endTime.atStartOfDay());
        }
        DeviceLife criteria = pageInfo.getCriteria();
        Optional.ofNullable(criteria).ifPresent(c -> {
            Optional.ofNullable(c.getDeviceId()).ifPresent(deviceId -> lqw.eq(DeviceLife::getDeviceId,deviceId));
            Optional.ofNullable(c.getStatus()).ifPresent(status -> lqw.eq(DeviceLife::getStatus,status));
        });
        lqw.orderByDesc(DeviceLife::getRecordTime);

        return deviceLifeMapper.selectPage(pageInfo.getPage(), lqw);
    }
}
